library libstrms32;

uses
  Windows,
  SysUtils,
  ActiveX,
  uLiteStream in 'uLiteStream.pas';

{$DEFINE UNREF_INTERFACE}
{$R *.res}

type
  HLSTREAM = pointer;

const
  STRM_ANSI = 0;
  STRM_UNICODE = 1;

procedure __assert(func: string; e: Exception);
begin
end;

const
  ccLibVersion = '1.0.4'{$IFDEF UNREF_INTERFACE}+' UI'{$ELSE}+' I'{$ENDIF};

{* DLL Exports *}

function lsStreamVersion(): PAnsiChar; stdcall;
begin
  Result := ccLibVersion;
end;

function lsStreamCreateFile(const FileName: pointer; const Flags: cardinal; const ShareRights: cardinal; out Stream: HLSTREAM): HResult; stdcall;
var strm: TLSFileStream;
begin
  Result := E_INVALIDARG;
  Stream := nil;
  try
    if (Filename=nil) then exit;
    strm := TLSFileStream.Create;
    case Flags of
      STRM_UNICODE: Result := strm.CreateFileW(widestring(PWideChar(FileName)), ShareRights);
      STRM_ANSI: Result := strm.CreateFileA(string(PChar(FileName)), ShareRights);
    end;
    if Failed(Result) then strm.Free
    else Stream := strm;
  except end;
end;

function lsStreamOpenFile(const FileName: pointer; const Flags: cardinal; const AccessRights, ShareRights: cardinal; out Stream: HLSTREAM): HResult; stdcall;
var strm: TLSFileStream;
begin
  Result := E_INVALIDARG;
  Stream := nil;
  try
    if (Filename=nil) then exit;
    strm := TLSFileStream.Create;
    case Flags of
      STRM_ANSI: Result := strm.OpenFileA(string(PChar(FileName)), AccessRights, ShareRights);
      STRM_UNICODE: Result := strm.OpenFileW(widestring(PWideChar(FileName)), AccessRights, ShareRights);
    end;
    if Failed(Result) then strm.Free
    else Stream := strm;
  except end;
end;

function lsStreamCreateUser(const Procs: USTRM_PROCS; const User: pointer): HLSTREAM; stdcall;
begin
  Result := nil;
  try
    Result := TUserStream.Create(Procs, User);
  except end;
end;

function lsStreamCreateMemory(const Size: cardinal): HLSTREAM; stdcall;
begin
  Result := nil;
  try
    Result := TLSMemoryStream.Create;
    if Size>0 then TLSMemoryStream(Result).SetSize(Size);
  except end;
end;

function lsStreamCreateMemoryLegacy(const Ptr: pointer; const Offset,Size: cardinal): HLSTREAM; stdcall;
begin
  Result := nil;
  try
    Result := TLegacyMemoryStream.CreateFrom(Ptr,Offset,Size);
  except end;
end;

function lsStreamCreateResource(Instance: THandle; Name, ResType: PChar; out Stream: HLSTREAM): HResult; stdcall;
var strm: TLSResourceStream;
begin
  Result := E_FAIL;
  Stream := nil;
  try
    strm := TLSResourceStream.Create;
    if not strm.Initialize(instance, Name, ResType) then begin
      Result := E_INVALIDARG;
      strm.Free;
      exit;
    end;

    Stream := strm;
    Result := S_OK;
  except end;
end;

function lsStreamQueryInterface(const lsStream: HLSTREAM; const IID: TGUID; out Obj): HResult; stdcall;
begin
  Result := E_POINTER;
  try
    if not (TObject(lsStream) is TBaseStream) then exit;
    Result := TBaseStream(lsStream).QueryInterface(IID, Obj);
  except
    on E: Exception do __assert('lsStreamQueryInterface()', E);
  end;
end;

function lsStreamFree(var lsStream: HLSTREAM): HResult; stdcall;
begin
  Result := E_POINTER;
  try
    if not (TObject(lsStream) is TBaseStream) then exit;
    TBaseStream(lsStream).Free;
    Result := S_OK; lsStream := nil;
  except
    on E: Exception do __assert('lsStreamFree()', E);
  end;
end;

function lsStreamIOCaps(const lsStream: HLSTREAM; out Caps: longint): HResult; stdcall;
begin
  Result := E_POINTER;
  try
    if not (TObject(lsStream) is TBaseStream) then exit;
    Caps := TBaseStream(lsStream).IOCaps;
    Result := S_OK;
  except
    on E: Exception do __assert('lsStreamIOCaps()', E);
  end;
end;

function lsStreamSeek(const lsStream: HLSTREAM; const Offset: int64; const Origin: longint; out NewPosition: int64): HResult; stdcall;
begin
  Result := E_POINTER;
  try
    if not (TObject(lsStream) is TBaseStream) then exit;
    Result := TBaseStream(lsStream).Seek(Offset, Origin, NewPosition);
  except
    on E: Exception do __assert('lsStreamSeek()', E);
  end;
end;

function lsStreamGetSize(const lsStream: HLSTREAM; out StreamSize: int64): HResult; stdcall;
begin
  Result := E_POINTER;
  try
    if not (TObject(lsStream) is TBaseStream) then exit;
    StreamSize := TBaseStream(lsStream).Size;
    Result := S_OK;
  except
    on E: Exception do __assert('lsStreamGetSize()', E);
  end;
end;

function lsStreamSetSize(const lsStream: HLSTREAM; const StreamSize: int64): HResult; stdcall;
begin
  Result := E_POINTER;
  try
    if not (TObject(lsStream) is TBaseStream) then exit;
    Result := TBaseStream(lsStream).SetSize(StreamSize);
  except
    on E: Exception do __assert('lsStreamSetSize()', E);
  end;
end;

function lsStreamRead(const lsStream: HLSTREAM; const Buffer; const BufferSz: longword; BytesRead: Plongint): HResult; stdcall;
begin
  Result := E_POINTER;
  try
    if not (TObject(lsStream) is TBaseStream) then exit;
    Result := TBaseStream(lsStream).Read(@Buffer, BufferSz, BytesRead);
  except
    on E: Exception do __assert('lsStreamRead()', E);
  end;
end;

function lsStreamWrite(const lsStream: HLSTREAM; const Buffer; const BufferSz: longword; BytesWritten: Plongint): HResult; stdcall;
begin
  Result := E_POINTER;
  try
    if not (TObject(lsStream) is TBaseStream) then exit;
    Result := TBaseStream(lsStream).Write(@Buffer, BufferSz, BytesWritten);
  except
    on E: Exception do __assert('lsStreamWrite()', E);
  end;
end;

exports
  lsStreamVersion,
  
  lsStreamCreateFile,
  lsStreamOpenFile,
  lsStreamCreateUser,
  lsStreamCreateMemory,
  lsStreamCreateMemoryLegacy,
  lsStreamCreateResource,

  lsStreamQueryInterface,
  lsStreamFree,
  lsStreamIOCaps,
  lsStreamSeek,
  lsStreamGetSize,
  lsStreamSetSize,
  lsStreamRead,
  lsStreamWrite;

end.
